from flask import Flask,request,jsonify,make_response,Response
from encrypt_aes import EncryptAES
import json
from init import VERSION, hangzhou_public_oss_bucket, shanghai_public_oss_bucket, table_client, docmind_client, appcode
from utils import parse_request_json, response_aes_encrypt_json, current_time_format
import time
from tablestore import *
from tablestore import OTSClient
import requests

def module_path(path):
    return '/pdf/'+VERSION+"/"+path


app = Flask(__name__)

# 错误类型拦截
@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

# 错误类型拦截
@app.errorhandler(500)
def in_error(error):
    return make_response(jsonify({'error': 'server inner error'}), 500)


# 获取上传至oss的文件url
@app.route(module_path('fileupload'), methods = ["POST"])
def text_upload_oss():

    request_form = parse_request_json(request.form)
    
    # 这里是为了防范其他app恶意攻击上传文件
    if "app" not in request_form:
        return response_aes_encrypt_json({},0,"app no exist")

    if "origin_format" not in request_form:
        return response_aes_encrypt_json({},0,"origin_format no exist")
    
    if "target_format" not in request_form:
        return response_aes_encrypt_json({},0,"target_format no exist")
    
    if "task" not in request_form:
        return response_aes_encrypt_json({},0,"task no exist")


    task = request_form["task"]
    origin_format = request_form["origin_format"]
    target_format = request_form["target_format"]

    config = {
        "task":task,
        "origin_format":origin_format,
        "target_format":target_format
    }
    if "password" in request_form:
        config["password"] = request_form["password"]
    if "start_page" in request_form:
        config["start_page"] = request_form["start_page"]
    if "end_page" in request_form:
        config["end_page"] = request_form["end_page"]
    if "ocr" in request_form:
        config["ocr"] = int(request_form["ocr"])
    if "language" in request_form:
        config["language"] = request_form["language"]
    

    # 使用的平台， third or aliyun  
    use_platform = "third" # aliyun

    if "use_platform" in request_form:
        use_platform = request_form["use_platform"]
    
    public_oss_bucket = shanghai_public_oss_bucket

    if use_platform == "aliyun":
        public_oss_bucket = hangzhou_public_oss_bucket

    # 生成id
    request_id = request.headers.get('X-Fc-Request-Id')
    
    # 写入table
    # print(config)
    # print(request_id)
    table_client.write_one_row("tb_request",{"id":request_id},config)

    headers = {
        "Content-Type" : "application/octet-stream" ,#mulipart/form-data
        "x-oss-storage-class": "Standard"
    }
    object_name = task + "/" + request_id + "."+origin_format

    # 生成上传文件的签名URL，有效时间为1800秒。30分钟有效
    # 默认情况下，OSS会根据Object完整路径中的正斜线（/）对URL进行转义，例如Object完整路径为/doc/test.txt，则生成的签名URL为/doc/test.txt。
    # 生成签名URL时，OSS默认会对Object完整路径中的正斜线（/）进行转义，从而导致生成的签名URL无法直接使用。
    # 设置slash_safe为True，OSS不会对Object完整路径中的正斜线（/）进行转义，此时生成的签名URL可以直接使用。
    url = public_oss_bucket.sign_url('PUT', object_name, 1800, slash_safe=True, headers=headers)

    return response_aes_encrypt_json({"file_id":request_id,"upload_url":url})
    pass


# 轮训是否处理完成
@app.route(module_path('fetchfile'), methods = ["POST"])
def fetch_file():
    
    request_form = parse_request_json(request.form)
    if "file_id" not in request_form:
        return response_aes_encrypt_json({},0,"file_id no exist")
    
    file_id = request_form["file_id"]
    
    #根据这个id 获取storetable中的 文档处理id
    row_info = table_client.get_one_row("tb_request",{"id":file_id})
    if row_info is None:
        #还没有处理到这个任务id或者这个id不存在
        return response_aes_encrypt_json({
            "status": "pending",
            "code":"wait",
            "type":"",
            "file_url":""
        })

    print(row_info)
    row_info_columns = row_info["columns"]
    token = row_info_columns["token"]
    target_format = row_info_columns["target_format"]

    if token.find("docmind-") >= 0:
        # 是来自 阿里云的 文档智能的token
        docmind_request = docmind_api20220711_models.GetDocumentConvertResult(
            # id :  任务提交接口返回的id
            id=request_id
        )
        try:
            # 复制代码运行请自行打印 API 的返回值
            response = docmind_client.get_document_convert_result(docmind_request)
            # # API返回值格式层级为 body -> data -> 具体属性。可根据业务需要打印相应的结果。获取属性值均以小写开头
            # # 获取异步任务处理情况,可根据response.body.completed判断是否需要继续轮询结果
            # print(response.body.completed)
            # # 获取返回结果。建议先把response.body.data转成json，然后再从json里面取具体需要的值。
            # print(response.body.data)        
            if response.body.completed:
                if response.body.status == "Success":
                    # 成功
                    file_url = response.body.data.url
                    c
                else:
                    #失败
                    return response_aes_encrypt_json({
                        "status": "done",
                        "code":"fail",
                        "type":"",
                        "file_url":""
                    })
            else:
                # 还在处理
                return response_aes_encrypt_json({
                    "status": "doing",
                    "code":"processing",
                    "type":"",
                    "file_url":""
                })
        except Exception as error:
            print(error)
            return response_aes_encrypt_json({
                "status": "done",
                "code":"fail",
                "type":"",
                "file_url":""
            })
    else:
        # 是来自第三方平台 度惠 token
        headers = {"Authorization":"APPCODE "+appcode}
        params = {
            "token":token
        }
        response = requests.get("https://api.duhuitech.com/q",headers=headers,params=params)

        if response.status_code == 200:
            response_json = response.json()
            response_result = response_json["result"]
            if response_result["status"] == "Pending":
                # 还未开始
                return response_aes_encrypt_json({
                    "status": "pending",
                    "code":"wait",
                    "type":"",
                    "file_url":""
                })
            elif response_result["status"] == "Doing":
                # 还在处理
                return response_aes_encrypt_json({
                    "status": "doing",
                    "code":"processing",
                    "progress":response_result["progress"],
                    "type":"",
                    "file_url":""
                })
            elif response_result["status"] == "Done":
                # 处理成功
                return response_aes_encrypt_json({
                        "status": "done",
                        "code":"success",
                        "type":target_format,
                        "file_url":response_result["fileurl"]
                    })
            else:
                # 处理失败
                return response_aes_encrypt_json({
                    "status": "done",
                    "code":"fail",
                    "type":"",
                    "file_url":""
                })
        else:
            print(response.text)
            print(response.status_code)
            print(response.headers)
            print(response.reason)
            print(response.url)
            # 处理失败
            return response_aes_encrypt_json({
                "status": "done",
                "code":"fail",
                "type":"",
                "file_url":""
            })

    pass


# 测试这个函数启用
@app.route(module_path('testrun'), methods = ["GET"])
def testrun():
    # appinfo = table_client.get_one_row("app",[('app_name','paper')])
    # if appinfo is None:
    #     appinfo = {"msg":"unkown info"}
    return make_response({"data":"testrun"})

if __name__ == "__main__":
    app.debug = True
    app.run(host="0.0.0.0", port=9000)

    # 查询app信息
    # app = table_client.get_one_row("app",[('app_name','paper')])
    # print(app)



